package com.huixuebao.after.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.huixuebao.after.dto.BaseDivisionDTO;
import com.huixuebao.after.dto.MechanismChildDTO;
import com.huixuebao.after.dto.MechanismDTO;
import com.huixuebao.after.dto.MerchantsDTO;
import com.huixuebao.after.entity.BaseDivisionEntity;
import com.huixuebao.after.entity.MechanismEntity;
import com.huixuebao.after.entity.UserEntity;
import com.huixuebao.after.mapper.BaseDivisionMapper;
import com.huixuebao.after.mapper.MechanismMapper;
import com.huixuebao.after.mapper.UserMapper;
import com.huixuebao.after.service.MachanismService;
import com.huixuebao.common.bean.ApiResult;
import com.huixuebao.common.enumeration.ResultCodeEnum;
import com.huixuebao.common.util.ConvertUtils;
import com.huixuebao.common.util.JWTUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;

@Slf4j
@Service
public class MachanismServiceImpl implements MachanismService {

    @Autowired
    MechanismMapper mechanismMapper;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private BaseDivisionMapper baseDivisionMapper;

    @Autowired
    private UserMapper userMapper;

    @Override
    public ApiResult<List<MechanismDTO>> saveMechanismDTO(List<MechanismDTO> list) {
        if (CollUtil.isNotEmpty(list)) {
            for (MechanismDTO mechanismDTO : list) {
                MechanismEntity entity = mechanismMapper.selectOne(new LambdaQueryWrapper<MechanismEntity>().eq(MechanismEntity::getUserNubmer, mechanismDTO.getUserNubmer()));
                if (ObjectUtil.isNotNull(entity)) {
                    BeanUtil.copyProperties(mechanismDTO, entity);
                    entity.setPid("100000000000000000000000001");
                    mechanismMapper.updateById(entity);
                } else {
                    entity = new MechanismEntity();
                    BeanUtil.copyProperties(mechanismDTO, entity);
                    entity.setId(IdUtil.fastSimpleUUID());
                    entity.setPid("100000000000000000000000001");
                    mechanismMapper.insert(entity);

                }
            }
        }
        ApiResult apiResult = new ApiResult();
        apiResult.setData(list);
        return apiResult;
    }

    /**
     * 返回机构列表
     * @param current
     * @param size
     * @param cityIds
     * @param merchantsName
     * @param merchantsState
     * @return
     */
    @Override
    public ApiResult getMerchantsList(Integer current, Integer size, String cityIds, String merchantsName, String merchantsState,String contactsName,
                                      String contactsPhone,HttpServletRequest request) {
        ApiResult apiResult = new ApiResult();
        try {
            String userId = JWTUtils.getUserId(request);
            String userType = JWTUtils.getUserType(request);
            LambdaQueryWrapper<MechanismEntity> lambdaQuery = new LambdaQueryWrapper<MechanismEntity>().orderByDesc(MechanismEntity::getCreateTime);
            UserEntity id = userMapper.selectOne(new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getId, userId));
            //MechanismEntity mechanismEntity = mechanismMapper.selectOne(new LambdaQueryWrapper<MechanismEntity>().eq(MechanismEntity::getId, id.getMechanismId()));

            if (ObjectUtil.isNotEmpty(cityIds)) {
                String[] cityIdArr = cityIds.split(",");
                for (int i = 0; i < cityIdArr.length; i++) {
                    if (i == 0) {
                        //查询省
                        lambdaQuery.eq(MechanismEntity::getProvince, cityIdArr[i]);
                    } else if (i == 1) {
                        //查询市
                        lambdaQuery.eq(MechanismEntity::getCity, cityIdArr[i]);
                    } else if (i == 2) {
                        //查询区
                        lambdaQuery.eq(MechanismEntity::getArea, cityIdArr[i]);
                    }
                }
            }
            if (ObjectUtil.isNotNull(current) && ObjectUtil.isNotNull(size)) {
                if ("0".equals(userType)){
                    log.info("userType是0");
                    IPage<MechanismEntity> page = new Page<>(current,size);
                    lambdaQuery.like(StrUtil.isNotBlank(merchantsName), MechanismEntity::getName, merchantsName)
                               .like(StrUtil.isNotBlank(merchantsState), MechanismEntity::getState, merchantsState)
                               .like(StrUtil.isNotBlank(contactsName),MechanismEntity::getContactsName,contactsName)
                               .like(StrUtil.isNotBlank(contactsPhone),MechanismEntity::getContactsPhone,contactsPhone);
                    IPage<MechanismEntity> entityPage = mechanismMapper.selectPage(page, lambdaQuery);

                    IPage<MerchantsDTO> dtoPage = ConvertUtils.convertToDTOPage(entityPage, MerchantsDTO.class);
                    apiResult.setData(dtoPage);
                    apiResult.setSuccess(true);
                    apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
                    apiResult.setMessage("管理端查询机构列表成功!!!");
                } else {
                    UserEntity ue = userMapper.selectById(userId);
                    IPage<MechanismEntity> page = new Page<>(current, size);
                    MerchantsDTO mdto = new MerchantsDTO();
                    mdto.setId(ue.getMechanismId());
                    getChilds1(mdto);
                    List<String> list = new ArrayList<>();
                    getIdList(mdto, list);
                    lambdaQuery.in(MechanismEntity::getId, list)
                            .like(StrUtil.isNotBlank(merchantsName), MechanismEntity::getName, merchantsName)
                            .like(StrUtil.isNotBlank(merchantsState), MechanismEntity::getState, merchantsState)
                            .like(StrUtil.isNotBlank(contactsName),MechanismEntity::getContactsName,contactsName)
                            .like(StrUtil.isNotBlank(contactsPhone),MechanismEntity::getContactsPhone,contactsPhone);
                    IPage<MechanismEntity> entityPage = mechanismMapper.selectPage(page, lambdaQuery);
                    IPage<MerchantsDTO> dtoPage = ConvertUtils.convertToDTOPage(entityPage, MerchantsDTO.class);
                    apiResult.setData(dtoPage);
                    apiResult.setSuccess(true);
                    apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
                    apiResult.setMessage("获取机构分页列表成功!!!!");
                }
            } else {
                //管理端端
                if("0".equals(userType)) {
                    List<MechanismEntity> list = mechanismMapper.selectList(null);
                    List<MerchantsDTO> dtoList = ConvertUtils.convertToDTOList(list, MerchantsDTO.class);
                    apiResult.setData(dtoList);
                    apiResult.setSuccess(true);
                    apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
                    apiResult.setMessage("获取机构列表信息成功!!");
                }else {
                    //商户/机构端端只显示机构
                    List<MechanismEntity> page = new ArrayList<>();
                    MerchantsDTO mdto = new MerchantsDTO();
                    mdto.setId(id.getMechanismId());
                    getChilds1(mdto);
                    List<String> list = new ArrayList<>();
                    getIdList(mdto, list);
                    lambdaQuery.in(MechanismEntity::getId, list);
                    List<MechanismEntity> entityPage = mechanismMapper.selectList(lambdaQuery);
                    List<MerchantsDTO> dtoPage = ConvertUtils.convertToDTOList(entityPage, MerchantsDTO.class);
                    apiResult.setData(dtoPage);
                    apiResult.setSuccess(true);
                    apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
                    apiResult.setMessage("获取机构分页列表成功!!!!");
                }
            }
        } catch (Exception e) {
            apiResult.setSuccess(false);
            apiResult.setCode(ResultCodeEnum.FAILURE.getCode());
            apiResult.setMessage("获取机构列表失败!!");
        }
        return apiResult;
    }

    @Override
    public ApiResult addMerchants(MerchantsDTO merchantsDTO,HttpServletRequest request) {
        ApiResult apiResult = new ApiResult();
        try {
            String name = merchantsDTO.getName();
            String businessLicens = merchantsDTO.getBusinessLicens();
            String brand = merchantsDTO.getBrand();
            String address = merchantsDTO.getAddress();
            String contactsName = merchantsDTO.getContactsName();
            String position = merchantsDTO.getPosition();
            String contactsPhone = merchantsDTO.getContactsPhone();
            String cityId = merchantsDTO.getCityId();

            String businessLicensAddress = merchantsDTO.getBusinessLicensAddress();
            String userId = JWTUtils.getUserId(request);
            String corporation = merchantsDTO.getCorporation();

            String gratisClassHour = merchantsDTO.getGratisClassHour();
            String insureRestrict = merchantsDTO.getInsureRestrict();
            String isCollaborate = merchantsDTO.getIsCollaborate();
            String mechanismUrl = merchantsDTO.getMechanismUrl();
            String mechanismIntroduce = merchantsDTO.getMechanismIntroduce();
            String isInsure = merchantsDTO.getIsInsure();
            UserEntity id = userMapper.selectOne(new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getId, userId));
            String mechanismId = id.getMechanismId();
            //判断非必填字段
            if(StrUtil.isNotEmpty(gratisClassHour) && StrUtil.isNotEmpty(insureRestrict) && StrUtil.isNotEmpty(isCollaborate)
            && StrUtil.isNotEmpty(mechanismUrl)&& StrUtil.isNotEmpty(mechanismIntroduce)&&StrUtil.isNotEmpty(isInsure)){
                MechanismEntity mechanismEntity = new MechanismEntity();
                mechanismEntity.setId(IdUtil.fastSimpleUUID());
                mechanismEntity.setName(name);
                mechanismEntity.setBrand(brand);
                mechanismEntity.setBusinessLicens(businessLicens);
                mechanismEntity.setAddress(address);
                mechanismEntity.setContactsName(contactsName);
                mechanismEntity.setPosition(position);
                mechanismEntity.setCreateTime(new DateTime());
                mechanismEntity.setContactsPhone(contactsPhone);
                mechanismEntity.setCityId(cityId);
                mechanismEntity.setPid(mechanismId);
                mechanismEntity.setCorporation(corporation);
                mechanismEntity.setBusinessLicensAddress(businessLicensAddress);
                mechanismEntity.setGratisClassHour(gratisClassHour);
                mechanismEntity.setInsureRestrict(insureRestrict);
                mechanismEntity.setIsCollaborate(isCollaborate);
                mechanismEntity.setMechanismUrl(mechanismUrl);
                mechanismEntity.setMechanismIntroduce(mechanismIntroduce);
                mechanismEntity.setIsInsure(isInsure);
                mechanismEntity.setState("1");
                //将前端传传入的城市id进行切分，然后分批插入到省、市、区数据中
                if (StringUtils.isNotBlank(merchantsDTO.getCityId())) {
                    List<String> citys = Arrays.asList(merchantsDTO.getCityId().split(","));
                    for (int i = 0; i < citys.size(); i++) {
                        if (i == 0) {
                            mechanismEntity.setProvince(citys.get(i));
                        } else if (i == 1) {
                            mechanismEntity.setCity(citys.get(i));
                        } else if (i == 2) {
                            mechanismEntity.setArea(citys.get(i));
                        }
                    }
                }
                mechanismMapper.insert(mechanismEntity);
                apiResult.setSuccess(true);
                apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
                apiResult.setMessage("添加机构信息成功!!");
            }
        } catch (Exception e) {
            log.info("添加机构信息失败！！");
            apiResult.setSuccess(false);
            apiResult.setCode(ResultCodeEnum.FAILURE.getCode());
            apiResult.setMessage("添加机构信息失败!!");
        }
        return apiResult;
    }

    /**
     * 获取全国区码表信息，首先查redis中有没有树结构，没有去数据库中查询，
     * 查询好了保存到redis中一份，
     * 后续进行区码表读取封装，直接调用方法即可。
     * @return
     */
    @Override
    public ApiResult<List<BaseDivisionDTO>> getAreaTree() {
        ApiResult apiResult = new ApiResult();
        try {
            String areaTree = redisTemplate.opsForValue().get("list");
            List<BaseDivisionDTO> cacheTree = JSONObject.parseArray(areaTree, BaseDivisionDTO.class);
            if (StringUtils.isEmpty(areaTree)) {
                List<BaseDivisionDTO> baseDivision = listDTO("86");
                List<BaseDivisionDTO> tree = new ArrayList<>();
                for (BaseDivisionDTO dto : baseDivision) {
                    getChilds(dto);
                }
                String jsonString = JSON.toJSON(tree).toString();
                redisTemplate.opsForValue().set("list", jsonString);
                apiResult.setData(tree);
                apiResult.setSuccess(true);
                apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
                apiResult.setMessage("获取地区码成功，走数据库读取!!");
                return apiResult;
            } else {
                log.info("获取地区码成功，从redis读取!!");
                apiResult.setData(cacheTree);
                apiResult.setSuccess(true);
                apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
                apiResult.setMessage("从reids获取数据成功!!");
                return apiResult;
            }
        } catch (Exception e) {
            apiResult.setSuccess(false);
            apiResult.setCode(ResultCodeEnum.FAILURE.getCode());
            apiResult.setMessage("获取地区码失败!!");
        }
        return apiResult;
    }

    @Override
    public ApiResult getLicenseOCR(String imagePhoto) {
        return new ApiResult();
    }

    /**
     * 编辑机构信息
     * @param merchantsDTO
     * @return
     */
    @Override
    public ApiResult editMerchants(MerchantsDTO merchantsDTO) {
        ApiResult apiResult = new ApiResult();
        try {
            String id = merchantsDTO.getId();
            String brand = merchantsDTO.getBrand();
            String businessLicens = merchantsDTO.getBusinessLicens();
            String address = merchantsDTO.getAddress();
            String contactsName = merchantsDTO.getContactsName();
            String position = merchantsDTO.getPosition();
            String contactsPhone = merchantsDTO.getContactsPhone();
            String cityId = merchantsDTO.getCityId();
            String state = merchantsDTO.getState();
            String name = merchantsDTO.getName();
            if (StrUtil.isNotEmpty(id) || StrUtil.isNotEmpty(name) || StrUtil.isNotEmpty(businessLicens)) {
                MechanismEntity editMerchants = mechanismMapper.selectOne(new LambdaQueryWrapper<MechanismEntity>().eq(MechanismEntity::getId, id));
                if (editMerchants == null) {
                    apiResult.setSuccess(false);
                    apiResult.setCode(ResultCodeEnum.FAILURE.getCode());
                    apiResult.setMessage("当前机构为空!!");
                } else {
                    editMerchants.setName(name);
                    editMerchants.setCityId(cityId);
                    editMerchants.setContactsPhone(contactsPhone);
                    editMerchants.setContactsName(contactsName);
                    editMerchants.setPosition(position);
                    editMerchants.setAddress(address);
                    editMerchants.setBrand(brand);
                    editMerchants.setState(state);
                    if (ObjectUtil.isNotEmpty(cityId)) {
                        String[] cityIdArr = cityId.split(",");
                        for (int i = 0; i < cityIdArr.length; i++) {
                            if (i == 0) {
                                //查询省
                                editMerchants.setProvince(cityIdArr[i]);
                            } else if (i == 1) {
                                //查询市
                                editMerchants.setCity(cityIdArr[i]);
                            } else if (i == 2) {
                                //查询区
                                editMerchants.setArea(cityIdArr[i]);
                            }
                        }
                    }
                    mechanismMapper.updateById(editMerchants);
                    apiResult.setSuccess(true);
                    apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
                    apiResult.setMessage("编辑机构信息成功!!");
                }
            } else {
                log.info("必填字段不能为空!!");
                apiResult.setSuccess(false);
                apiResult.setCode(ResultCodeEnum.FAILURE.getCode());
                apiResult.setMessage("必填字段不能为空!!");
            }
        } catch (Exception e) {
            apiResult.setSuccess(false);
            apiResult.setCode(ResultCodeEnum.FAILURE.getCode());
            apiResult.setMessage("编辑机构新消息失败!!");
        }
        return apiResult;
    }

    /**
     * 获取商户基础信息
     * @return
     */
    @Override
    public ApiResult getMerchantsNews(HttpServletRequest request) {
        ApiResult apiResult = new ApiResult();
        try {
            String userId = JWTUtils.getUserId(request);
            UserEntity userIds = userMapper.selectOne(new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getId, userId));
            MechanismEntity mechanismInfor = mechanismMapper.selectOne(new LambdaQueryWrapper<MechanismEntity>().eq(MechanismEntity::getId, userIds.getMechanismId()));
            MerchantsDTO merchantsDTO = new MerchantsDTO();
            merchantsDTO.setIdType(mechanismInfor.getIdType());
            merchantsDTO.setName(mechanismInfor.getName());
            merchantsDTO.setContactsName(mechanismInfor.getContactsName());
            merchantsDTO.setBusinessLicens(mechanismInfor.getBusinessLicens());
            merchantsDTO.setCorporation(mechanismInfor.getCorporation());
            merchantsDTO.setBusinessLicensAddress(mechanismInfor.getBusinessLicensAddress());
            merchantsDTO.setContactsPhone(mechanismInfor.getContactsPhone());
            merchantsDTO.setAddress(mechanismInfor.getAddress());
            apiResult.setData(merchantsDTO);
            apiResult.setSuccess(true);
            apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
            apiResult.setMessage("获取机构信息成功!!");
        } catch (Exception e) {
            log.info("获取本商户信息失败!!");
            apiResult.setSuccess(false);
            apiResult.setCode(ResultCodeEnum.FAILURE.getCode());
            apiResult.setMessage("获取本商户信息异常!!" + e.getMessage());
        }
        return apiResult;
    }

    /**
     * 查看机构自己的子机构
     * @param request
     * @return
     */
    @Override
    public ApiResult getChildrenMerchant(HttpServletRequest request) {
        ApiResult apiResult = new ApiResult();
        try {
            String userId = JWTUtils.getUserId(request);
            UserEntity id = userMapper.selectOne(new LambdaQueryWrapper<UserEntity>().eq(UserEntity::getId, userId));
            String mechanismId = id.getMechanismId();
            MechanismEntity mechanismEntity = mechanismMapper.selectOne(new LambdaQueryWrapper<MechanismEntity>().eq(MechanismEntity::getId,mechanismId));
            MerchantsDTO dto =new MerchantsDTO();
            MechanismChildDTO mechanismChildDTO = new MechanismChildDTO();
            mechanismChildDTO.setData(dto);
            BeanUtil.copyProperties(mechanismEntity,dto);
            getChilds1(dto);
            apiResult.setData(mechanismChildDTO);
            apiResult.setSuccess(true);
            apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
            apiResult.setMessage("查询子集机构成功!!!");
        }catch (Exception e){
            log.info("查询子集机构异常!!!");
            apiResult.setSuccess(false);
            apiResult.setCode(ResultCodeEnum.SUCCESS.getCode());
            apiResult.setMessage("查询子集机构失败!!!");
        }
        return apiResult;
    }

    private List<BaseDivisionDTO> listDTO(String pid) {
        List<BaseDivisionEntity> list = baseDivisionMapper.selectList(new LambdaQueryWrapper<BaseDivisionEntity>().eq(BaseDivisionEntity::getPId, pid));
        List<BaseDivisionDTO> result = new ArrayList<>();
        list.forEach(entity -> {
            BaseDivisionDTO dto = new BaseDivisionDTO();
            BeanUtil.copyProperties(entity, dto);
            result.add(dto);
        });
        return result;
    }

    private void getChilds(BaseDivisionDTO dto) {
        List<BaseDivisionDTO> childs = listDTO(dto.getId());
        dto.setChildren(childs);
        for (BaseDivisionDTO getChilds : childs) {
            getChilds(getChilds);
        }
    }
    private List<MerchantsDTO> listDTO1(String pid) {
        List<MechanismEntity> list = mechanismMapper.selectList(new LambdaQueryWrapper<MechanismEntity>().eq(MechanismEntity::getPid, pid));
        List<MerchantsDTO> result = new ArrayList<>();
        list.forEach(entity -> {
            MerchantsDTO dto = new MerchantsDTO();
            BeanUtil.copyProperties(entity, dto);
            result.add(dto);
        });
        return result;
    }

    private void getChilds1(MerchantsDTO dto) {
        List<MerchantsDTO> childs = listDTO1(dto.getId());
        dto.setChildren(childs);
        for (MerchantsDTO getChilds : childs) {
            getChilds1(getChilds);
        }
    }

    private void getIdList(MerchantsDTO dto,List<String> ids){
        ids.add(dto.getId());
        dto.getChildren().forEach((merchantsDTO)->{
            getIdList(merchantsDTO,ids);
        });
    }

}
